﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace YunLuPos.Printer
{
    public abstract class PrintBase
    {
        private int ColWidth = 32;
        public enum PT { COM, LPT, USB }

        public enum HorPos { Left, Center, Right }
        /// <summary>
        /// 打印接口，所有的打印方法都需要实现该接口
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public abstract bool write(byte[] b);

        /// <summary>
        /// 打印空白行
        /// </summary>
        /// <returns></returns>
        public abstract bool NewRow();
        /// <summary>
        /// 初始化打印实现类
        /// </summary>
        /// <returns></returns>
        public abstract bool initPrinter();

        /// <summary>
        /// 初始化打印实现类
        /// </summary>
        /// <returns></returns>
        public abstract bool open();

        /// <summary>
        /// 释放
        /// </summary>
        /// <returns></returns>
        public abstract bool Dispose();

        /// <summary>
        /// 打印一行字符 不换行
        /// </summary>
        /// <param name="Data"></param>
        /// <returns></returns>
        public bool write(string Data)
        {
            byte[] bData = System.Text.Encoding.Default.GetBytes(Data);
            return write(bData);
        }

        /// <summary>
        /// 打印一行，打印成功后自动跳到下一行
        /// </summary>
        /// <param name="Data"></param>
        /// <returns></returns>
        public bool writeLine(string Data)
        {
            bool Result = write(Data);
            if (Result) Result = NewRow();
            return Result;
        }

        /// <summary>
        /// 指定位置打印一行数据
        /// </summary>
        /// <param name="Data"></param>
        /// <param name="horpos"></param>
        /// <returns></returns>
        public bool writeLine(string Data, HorPos horpos)
        {
            int Length = Encoding.Default.GetBytes(Data).Length;
            if (Length > ColWidth || HorPos.Left == horpos) return writeLine(Data);
            switch (horpos)
            {
                case HorPos.Center:
                    Data = Data.PadLeft(Length + (ColWidth - Length) / 2 - (Length - Data.Length), ' ');
                    break;
                case HorPos.Right:
                    Data = Data.PadLeft(ColWidth - (Length - Data.Length), ' ');
                    break;
                default:
                    break;
            }
            return writeLine(Data);
        }


        /// <summary>
        /// 打印列表,兼容农行银联小票 切纸功能
        /// </summary>
        /// <param name="list"></param>
        public void printList(List<String> list)
        {
            this.NewRow();
            if (list != null)
                list.ForEach(l =>
                {
                    if (l.StartsWith("CUTPAPER"))
                    {
                        Thread.Sleep(4 * 1000);
                    }
                    else
                    {
                        this.writeLine(l);
                    }
                });
        }


       
        /// <summary>
        /// 打印指定数目的空白行
        /// </summary>
        /// <param name="iRow"></param>
        /// <returns></returns>
        public bool NewRow(int iRow)
        {
            bool Result = false;
            for (int i = 0; i < iRow; i++)
            {
                Result = NewRow();
                if (!Result) break;
            }
            return Result;
        }

        /// <summary>
        /// 切纸
        /// </summary>
        /// <returns></returns>
        public bool CutPaper()
        {
            byte[] temp = new byte[] { 0x1D, 0x56, 0x00, 0x05 };
            return write(temp);
        }

        /// <summary>
        /// 打开钱箱
        /// </summary>
        public virtual void openMoneyBox()
        {
            byte[] bdata1 = { 0x1B, 0x70, 0x0, 0x3C, 0xFF };
            byte[] bdata2 = { 0x1B, 0x70, 0x7 };
            write(bdata1);
            write(bdata2);
        }

        public bool SetNormalFont()
        {
            byte[] temp;
            try
            {

                temp = new byte[] { 0x1D, 0x50, 0xB0, 0xB4 };
                write(temp);

                //1B, 53 选择标准模式
                temp = new byte[] { 0x1B, 0x53 };
                write(temp);

                //1B, 20 设置字符右间距
                temp = new byte[] { 0x1B, 0x20, 0x00 };
                write(temp);

                //设置汉字字符左右间距
                temp = new byte[] { 0x1C, 0x53, 0x00, 0x00 };
                write(temp);

                //1D 42 是否反选打印 01反选/00取消
                temp = new byte[] { 0x1D, 0x42, 0x00 };
                write(temp);

                //1B 45 选择/取消加粗模式 01选择/00取消
                temp = new byte[] { 0x1B, 0x45, 0x00 };
                write(temp);

                //1B 7B 选择/取消倒置打印模式 01选择/00取消
                temp = new byte[] { 0x1B, 0x7B, 0x00 };
                write(temp);

                //1B 2D 设置/取消下划线 01设置/00取消
                temp = new byte[] { 0x1B, 0x2D, 0x00 };
                write(temp);

                //1B 2D 设置/取消汉字下划线 01设置/00取消
                temp = new byte[] { 0x1C, 0x2D, 0x00 };
                write(temp);

                //选择取消顺时针旋转90度 01选择 00取消
                temp = new byte[] { 0x1B, 0x56, 0x00 };
                write(temp);

                //1B 45 选择/取消加粗模式 01选择/00取消
                temp = new byte[] { 0x1B, 0x45, 0x00 };
                write(temp);

                //1B 45 设置绝对打印位置 
                temp = new byte[] { 0x1B, 0x10, 0x00, 0x00 };
                write(temp);

                //1B, 33 设置行高, 18个像素
                temp = new byte[] { 0x1B, 0x33, 0x25 };
                write(temp);

                //1B 4D 选择字体 03为汉字字体
                //temp = new byte[] { 0x1B, 0x4D, 0x03 };
                //temp = new byte[] { 0x1B, 0x4D, 0x05 }; //
                //temp = new byte[] { 0x1B, 0x4D, 0x06 };//汉字及数字较正常
                temp = new byte[] { 0x1B, 0x21, 0x00 }; //
                write(temp);

                //1D 21 选择字体大小,默认
                // temp = new byte[] { 0x1D, 0x21, 0x00 };
                //serialPort.Write(temp, 0, temp.Length);
                return true;
            }

            catch { return false; }
        }

    }
}
